package com.cyz.user.userService.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyz.common.bean.Shop;
import com.cyz.common.bean.User;
import com.cyz.common.bean.UserRole;
import com.cyz.common.bean.UserShop;
import com.cyz.common.dto.ShopDto;
import com.cyz.common.dto.UserDto;
import com.cyz.common.mapper.UserRoleMapper;
import com.cyz.common.utils.*;
import com.cyz.user.dto.UserPasswordDto;
import com.cyz.common.enums.MyEnums;
import com.cyz.common.exception.MyException;
import com.cyz.common.mapper.UserMapper;
import com.cyz.common.security.MyUserDetails;
import com.cyz.user.userService.UserCardService;
import com.cyz.user.userService.UserShopService;
import com.cyz.user.userService.User_UserService;
import com.cyz.user.vo.LoginVo;
import com.cyz.user.vo.CardVo;
import com.cyz.user.vo.ShopVo;
import com.cyz.user.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
* @author 34928
* @description 针对表【user(用户表)】的数据库操作Service实现
* @createDate 2023-02-22 10:58:38
*/
@Service
public class UserUserServiceImpl extends ServiceImpl<UserMapper, User>
    implements User_UserService {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private MyRedisUtil myRedisUtil;
    @Autowired
    private UserCardService userCardService;
    @Autowired
    private UserShopService userShopService;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public String getAvatarById(Integer id) {
        //根据ID获取用户信息
        //获取用户头像
        return getById(id).getAvatar();
    }

    @Override
    public R toRegister(UserDto userDto) {
        if (!userDto.getPassword().equals(userDto.getNewPassword())){
            return R.error(MyEnums.NEW_PASSWORD_ERROR);
        }
        //转化dto
        User user = BeanCopyUtil.copyBean(userDto, User.class);
        //默认昵称
        user.setNickName("用户"+user.getUserName());
        //设置用户类型
        user.setType("0");
        //加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //添加数据
        boolean flag = save(user);
        userRoleMapper.save(new UserRole(user.getId(),2));
        //错误判断
        if(flag){
            return R.success();
        }
        //返回数据
        return R.error(MyEnums.ERROR);
    }

    @Override
    public R updateUser(UserDto userDto) {
        //转化dto
        User user = BeanCopyUtil.copyBean(userDto, User.class);
        //更新数据
        boolean flag = updateById(user);
        if(flag){
            //返回用户ID
            user = getById(user.getId());
            return R.success(user);
        }
        return R.error(MyEnums.UPDATE_FAIL);
    }

    @Override
    public R logout() {
        //获取当前登录用户信息
        Integer userId = SecurityUtils.getUserId();
        //删除redis中对应的值
//        redisUtil.deleteObject(MyEnums.USER_REDIS_NAME+userId);
        myRedisUtil.myDeleteKey(MyEnums.USER_REDIS_NAME+userId);
        //返回退出成功信息
        return R.success(MyEnums.SUCCESS_LOGOUT);
    }

    @Override
    public R queryMyShop() {
        List<Shop> list = userShopService.getShopsByUserId(SecurityUtils.getUserId());
        List<ShopVo> shopVos = BeanCopyUtil.copyBeanList(list, ShopVo.class);
        return R.success(shopVos);
    }

    @Override
    public R addMyShop(ShopDto shopDto) {
        UserShop userShop = new UserShop();
        userShop.setShopId(shopDto.getId());
        userShop.setUserId(Math.toIntExact(SecurityUtils.getUserId()));
        userShopService.save(userShop);
        return queryMyShop();
    }

    @Override
    public R login(UserDto userDto) {
        //将user信息封装到authentication
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUserName(),userDto.getPassword());
        //调用authenticate进行认证
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        //认证失败
        if(ObjectUtils.isEmpty(authentication)){
            throw new MyException(MyEnums.LOGIN_ERROR);
        }
        //认证成功取出数据
        MyUserDetails myUserDetails =(MyUserDetails) authentication.getPrincipal();
        if(!MyEnums.USER_TYPE_USER.equals(myUserDetails.getUser().getType())){
            throw new MyException(MyEnums.LOGIN_ERROR);
        }
        if(myUserDetails.getUser().getStatus().equals(MyEnums.USER_BAN)){
            throw new MyException(MyEnums.LOGIN_BAN);
        }
        //获取数据id
        Integer id = myUserDetails.getUser().getId();
        //根据id生成token
        String jwt = JwtUtil.createJWT(String.valueOf(id));
        //将数据存入redis
//        redisUtil.setCacheObject(MyEnums.USER_REDIS_NAME +id,myUserDetails);
        myRedisUtil.myStringSet(MyEnums.USER_REDIS_NAME + id, myUserDetails);
        //vo数据处理
        UserVo userVo = BeanCopyUtil.copyBean(myUserDetails.getUser(), UserVo.class);
//        //查询购买过的课程
//        LambdaQueryWrapper<UserShop> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(UserShop::getUserId,id);
//        //根据课程编号来查询课程具体信息
//        List<UserShop> userShops = userShopService.list(lambdaQueryWrapper);
//        List<Shop> shops
//        userShops.stream()
//                .map(UserShop::getShopId)
//                .forEach(item ->{
//
//                });
//
//
//        List<Integer> list = userShopService.list(lambdaQueryWrapper).stream().map(UserShop::getShopId).collect(Collectors.toList());
//        List shopByIds = shopService.getShopsById(list);

        //查询收藏的课程
        List<CardVo> cardVos = userCardService.getCardsByUserId(userVo.getId());
        LoginVo loginVo = new LoginVo(userVo,jwt,cardVos);
        //返回数据
        return R.success(loginVo);
    }

    @Override
    public R queryUserMsg() {
        Integer userId = SecurityUtils.getUserId();
        User user = getById(userId);
        UserVo userVo = BeanCopyUtil.copyBean(user, UserVo.class);
        return R.success(userVo);
    }

    @Override
    public R updateUserPassword(UserPasswordDto userPasswordDto) {
        // 获取当前登录用户的详细信息
        MyUserDetails loginUser = SecurityUtils.getLoginUser();
        // 比较输入的旧密码和当前用户的密码是否匹配
        boolean matches = passwordEncoder.matches(userPasswordDto.getOldPassword(),loginUser.getPassword());
        // 如果密码匹配，则创建一个新的User对象，设置其ID为当前用户的ID，将新密码加密并设置为新的密码
        if(matches){
            User user = new User();
            user.setId(loginUser.getUser().getId());
            user.setPassword(passwordEncoder.encode(userPasswordDto.getNewPassword()));
            // 将新密码更新到数据库中
            updateById(user);
            // 返回一个包含操作成功信息的R对象
            return R.success();
        }
        //如果密码不匹配，则返回一个包含错误信息的R对象
        else {
            return R.error(MyEnums.OLD_PASSWORD_ERROR);
        }
    }
}




